
#include "iostream"
#include <bitset>
#include <vector>
#include <sys/types.h>
#include <sys/stat.h>
#include "f_extern.h"
using namespace std;


int make_file(string host_file,string file_name, int parent_block)
{
	char name[10];
	int num_next = 0;
	int i,j,size;
	int new_dir_block;
	int file_head_block;
	int next_block;
	header head;
	header new_file;

	string path;
	string chld_path;
	FILE *ptr;
	FILE *fd;
	char *blob = new char[block_size - sizeof(int)];

	struct stat fs_stat;
	int file_block_size;
	if(stat(host_file.data(),&fs_stat)!=0) 
	{
#ifdef PRINT_MSG
		printf("[import]: Can't get extern file stats %s\n",host_file.data());
#endif
		return -1;
	};
	
	file_block_size = (fs_stat.st_size)/(block_size-sizeof(int))+2;
	if(file_block_size>get_num_free_blocks())
	{
#ifdef PRINT_MSG
		printf("[import]: Not enough free space. free blocks %d, need blocks %d\n",get_num_free_blocks(),file_block_size);
#endif
		return -2;
	}
	sprintf(name,"./.%d",parent_block);
	path = root_dir; path.append(name);
	fd = fopen(path.data(),"rb");
	fread(&head,sizeof(header),1,fd);
	fclose(fd);
	
	num_next = head.data_block; size = head.size;
	do
	{
		sprintf(name,"./.%d",num_next);
		path = root_dir; path.append(name);
		fd = fopen(path.data(),"rb");
		size -= (block_size-sizeof(int));
		fseek(fd,-sizeof(int),SEEK_END);
		fread(&num_next,sizeof(int),1,fd);
		fclose(fd);
	}while(num_next!=0);

	if(size ==0)
	{
		fd = fopen(path.data(),"rb+");
		new_dir_block = get_free_block();
		fseek(fd,-sizeof(int),SEEK_END);
		fwrite(&new_dir_block,sizeof(int),1,fd);
		fclose(fd);

		sprintf(name,"./.%d",new_dir_block);
		path = root_dir; path.append(name);
		fd = fopen(path.data(),"rb+");	
		file_head_block = get_free_block();
		fwrite(&file_head_block,sizeof(int),1,fd);

		new_dir_block = 0;
		fseek(fd,-sizeof(int),SEEK_END);
		fwrite(&new_dir_block,sizeof(int),1,fd);
		fclose(fd);
		
		head.size_in_block++;
	}
	else
	{
		size+=(block_size-sizeof(int));
		fd = fopen(path.data(),"rb+");
		
		fseek(fd,size,SEEK_SET);
		file_head_block = get_free_block();
		fwrite(&file_head_block,1,sizeof(int),fd);
		fclose(fd);
	}

	head.size+=sizeof(int);
	
	cout<<"set_time = "<<head.last_time<<endl;
	set_time(&head);
	cout<<"set_time = "<<head.last_time<<endl;
	
	sprintf(name,"./.%d",parent_block);
	path = root_dir; path.append(name);
	fd = fopen(path.data(),"rb+");
	fwrite(&head,sizeof(header),1,fd);
	fclose(fd);
	
	strcpy(new_file.name, file_name.data());
	set_time(&new_file);
	new_file.size = fs_stat.st_size;
	new_file.data_block = get_free_block();
	new_file.type = 1;
	new_file.last_time = 0;
	
	sprintf(name,"./.%d",file_head_block);
	path = root_dir; path.append(name);
	fd = fopen(path.data(),"rb+");
	fwrite(&new_file,sizeof(header),1,fd);
	fclose(fd);

	ptr = fopen(host_file.data(),"rb");
	size = new_file.size;
	next_block = new_file.data_block;
	while(size>=0)
	{
		
		sprintf(name,"./.%d",next_block);
		path = root_dir; path.append(name);
		fd = fopen(path.data(),"rb+");

		if(size>=(block_size-sizeof(int)))
		{
			fread(blob,(block_size-sizeof(int)),1,ptr);
			fwrite(blob,(block_size-sizeof(int)),1,fd);
		}
		else
		{
			fread(blob,size,1,ptr);
			fwrite(blob,size,1,fd);
		}
		
		fseek(fd,-sizeof(int),SEEK_END);
		size -= (block_size-sizeof(int));
		if(size>0) next_block = get_free_block();
		else next_block = 0;
		fwrite(&next_block,sizeof(int),1,fd);
		fclose(fd);
	}
	fclose(ptr);
	delete blob;
	return 0;
}

int find_dir(string dir_name, int base_block,int type )
{
	char name[10];
	int num_next = 0;
	int i,j;
	int num_chld;
	int cur_block_size,last_block_size;
	int tmp_size;
	header head;
	header new_dir;
	sprintf(name,"./.%d",base_block);
	string path = root_dir; path.append(name);
	string chld_path;
	FILE *ptr;
	FILE *fd = fopen(path.data(),"rb");
	fread(&head,1,sizeof(header),fd);
	fclose(fd);
	num_next = head.data_block;	
	tmp_size = head.size;
	do
	{
		sprintf(name,"./.%d",num_next);
		path = root_dir; path.append(name);
		fd = fopen(path.data(),"rb");
		for(j=0;j<head.size && j<block_size-(sizeof(int)); j+=sizeof(int))
		{

			fread(&num_chld,sizeof(int),1,fd);
			sprintf(name,"./.%d",num_chld);
			chld_path = root_dir; chld_path.append(name);
			
			ptr = fopen(chld_path.data(),"rb");
			fread(&new_dir,sizeof(header),1,ptr);
			
			fclose(ptr);
			
			if(strcmp(new_dir.name,dir_name.data())==0 && (new_dir.type ==type || type ==-1))
			{
				fclose(fd);
				return num_chld;
			}
		

		}
		head.size -= (block_size-sizeof(int));
		fseek(fd,-sizeof(int),SEEK_END);
		fread(&num_next,sizeof(int),1,fd);
		fclose(fd);
	}while(num_next!=0);
	

	return -1;
}

int main(int argc, char* argv[])
{	
	char* _f_ = "[import]";
	int next_dir_num = 0;
	int i;
	FILE* config = NULL; 
	FILE* block = NULL;
	string file_name;
	string host_file;
	int file_block_num;
	
	header dir;
	string dir_path;
	if (argc != 4){
#ifdef PRINT_MSG 
		printf("%s: Use import  root host_file fs_file\n",_f_); 
#endif
		return 2;
	}
	
		root_dir = argv[1];
		make_build_map(1);
		host_file = argv[2];

		dir_path = argv[3];
		parse_path(dir_path);	
		
		next_dir_num = 1;
		for( i = 0;i<dir_set.size()-1;i++)
		{
			next_dir_num = find_dir(dir_set[i],next_dir_num,0);
			if(next_dir_num<0)
				{
#ifdef PRINT_MSG
					printf("%s: Directory %s not exist\n",_f_, dir_set[i].data());
#endif	
					return 3;
				}
				
		}
		file_block_num = find_dir(dir_set[dir_set.size()-1],next_dir_num,0);
		if(file_block_num>0)
		{
#ifdef PRINT_MSG
			printf("%s: File %s already exist\n",_f_, dir_path.data());
#endif	
			return 4;
		}
		
		if( make_file(host_file, dir_set[dir_set.size()-1],next_dir_num) <0) return 5;
		else return 0;
}


